package com.cloudlinkin.util.hfx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cloudlinkin.constant.HfxSmsConstant;
import com.cloudlinkin.entity.HfxSendResult;
import com.cloudlinkin.util.AESEncryptUtil;
import com.cloudlinkin.util.Patterns;
import com.cloudlinkin.util.SignatureUtil;
import com.cloudlinkin.util._HttpKit;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.regex.Matcher;

/**
 * 和飞信短信下发工具类
 */
@Component
public class HfxSmsSendUtil {

    protected final Logger log = Logger.getLogger(this.getClass());
    /**和飞信短信下发接口地址*/
    @Value("${hfx_sms_send_url}")
    private String hfxSmsSendUrl;
    /**和飞信接口appkey*/
    @Value("${hfx_sms_appkey}")
    private String hfxSmsAppkey;
    /**和飞信渠道ID*/
    @Value("${hfx_sms_secretId}")
    private String hfxSmsSecretId;
    /**和飞信aeskey*/
    @Value("${hfx_sms_aeskey}")
    private String hfxSmsAeskey;

    /**和飞信企业ID(我方只注册一个使用)*/
    @Value("${hfx_sms_enterDeptId}")
    private String hfxSmsEnterDeptId;

    /**是否开启多模板功能  没开启则用只有一个模板变量的模板*/
    @Value("${is_open_multiple_templates}")
    private Boolean isOpenMultipleTemplates;

    /**和飞信通用模板ID*/
    // 模板中只有一个变量
    @Value("${hfx_sms_general_purpose_template_id1}")
    private Integer hfxSmsGeneralPurposeTemplateId1;
    @Value("${hfx_sms_general_purpose_template_prefix1}")
    private String hfxSmsGeneralPurposeTemplatePrefix1;
    // 模板中有两个变量 	 amount + url date
    @Value("${hfx_sms_general_purpose_template_id2}")
    private Integer hfxSmsGeneralPurposeTemplateId2;
    @Value("${hfx_sms_general_purpose_template_prefix2}")
    private String hfxSmsGeneralPurposeTemplatePrefix2;
    // 模板中有三个变量 amount + url + date
    @Value("${hfx_sms_general_purpose_template_id3}")
    private Integer hfxSmsGeneralPurposeTemplateId3;
    @Value("${hfx_sms_general_purpose_template_prefix3}")
    private String hfxSmsGeneralPurposeTemplatePrefix3;


    /**
     * 和飞信短信
     * @param content
     *          短信内容 未拼接模板前的
     * @param contactIds
     *                  联系人ID
     * @return
     *          当返回状态码是 1000 和1001时 数据从新如队列 重试   其他状态码 只记录错误日志即可
     */
    public HfxSendResult smsSend(String content, String contactIds) {

        // 组装参数
        String hfxParam = this.buildSMSSendParams(content, contactIds);

        if (StringUtils.isBlank(hfxParam)){ // 组装参数错误为空
            HfxSendResult hfxSendResult = new HfxSendResult();
            hfxSendResult.setHfxStatus(HfxSmsConstant.RETURN_STATUS_9999);
            hfxSendResult.setHfxMsg(HfxSmsConstant.RETURN_MSG_9999);
            return hfxSendResult;
        }

        HfxSendResult hfxSendResult = this.hfxSmsSend(hfxParam); // 开始下发
        return hfxSendResult;


    }

    /**
     * 和飞信短信下发
     * @param hfxParam
     *              使用和飞信短信下发时要提交的参数
     * @return
     */
    private HfxSendResult hfxSmsSend(String hfxParam) {
        String hfxResult = null; // 下发返回结果
        HfxSendResult hfxSendResult = new HfxSendResult(); // 返回下发结果
        // 如果通道异常重试下发三次
        for (int i = 0; i < 3; i++) {
            try {
                hfxResult = _HttpKit.postStringEntity(hfxSmsSendUrl, hfxParam, _HttpKit.UTF8, _HttpKit.APPLICATION_JSON).getStringMessage();

                } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (StringUtils.isNotBlank(hfxResult)) {
                break;
            }
        }

        // 提交失败
        if (StringUtils.isBlank(hfxResult)) {
            // 通道繁忙
            hfxSendResult.setHfxStatus(HfxSmsConstant.RETURN_STATUS_1000);
            hfxSendResult.setHfxMsg(HfxSmsConstant.RETURN_MSG_1000);
            return hfxSendResult;
        }

        // 提交成功
        JSONObject hfxResultJson = JSON.parseObject(hfxResult);
        String resCode;
        String taskId = null;

        if (HfxSmsConstant.HFX_REQUST_SUCCESS_0.equals(resCode = hfxResultJson.getJSONObject("resStatus").getString("resCode"))) {
            try {
                taskId = JSONObject.parseObject(AESEncryptUtil.aesDecrypt(hfxResultJson.getString("result"), AESEncryptUtil.getAESKey(hfxSmsAeskey))).getString("taskId");
            } catch (Exception e) {
                e.printStackTrace();
            }
            hfxSendResult.setHfxStatus(resCode);
            hfxSendResult.setHfxMsg(hfxResultJson.getJSONObject("resStatus").getString("resMsg"));
            hfxSendResult.setTaskId(taskId);
        }else {
            // 下发失败  // 获取下发失败原因
            hfxSendResult.setHfxStatus(resCode);
            hfxSendResult.setHfxMsg(hfxResultJson.getJSONObject("resStatus").getString("resMsg"));

        }


        return hfxSendResult;
    }


    /**
     *
     * @param content
     *              短信内容
     * @param contactIds
     *              企业联系人ID
     * @return
     * @throws Exception
     */
    private String buildSMSSendParams(String content,String contactIds) {

        try {
        Integer templateId = null;
        String placeHolderContent = null;

        if(!isOpenMultipleTemplates){ // 如果没有开启多模板  则不在进行模板拼接  直接使用单模板变量模板
            placeHolderContent = hfxSmsGeneralPurposeTemplatePrefix1.replace("$$amount$$", content);
            templateId = hfxSmsGeneralPurposeTemplateId1;
        }

        if(isOpenMultipleTemplates){ // 如果开启了多模板功能(在短信内容包含URL时给和飞信打广告的)

            // 短信类容中包含的URL
            String placeHolderURL;
            // 组装模板变量
            // 1剪切短信内容
            Matcher matcher = Patterns.WEB_URL.matcher(content);
            if (matcher.find()){ // 如果内容里面包含地址

                placeHolderURL = matcher.group(0);
                String urlBefore = content.substring(0, matcher.start());
                String urlAfter = content.substring(matcher.end());

                if (StringUtils.isBlank(urlAfter)) { // 如果url后面没有内容   选用两个变量的
                    placeHolderContent = hfxSmsGeneralPurposeTemplatePrefix2.replace("$$amount$$", urlBefore);
                    placeHolderContent = placeHolderContent.replace("$$url$$", " " + placeHolderURL + " ");
                    templateId = hfxSmsGeneralPurposeTemplateId2;
                }

                if (StringUtils.isNotBlank(urlAfter)) { // 如果url后面有内容   选用三个变量的
                    placeHolderContent = hfxSmsGeneralPurposeTemplatePrefix3.replace("$$amount$$", urlBefore);
                    placeHolderContent = placeHolderContent.replace("$$url$$", " " + placeHolderURL + " ");
                    placeHolderContent = placeHolderContent.replace("$$date$$", urlAfter);
                    templateId = hfxSmsGeneralPurposeTemplateId3;
                }

            }

            if (!matcher.find()){ // 如果内容里面不包含地址
                placeHolderContent = hfxSmsGeneralPurposeTemplatePrefix1.replace("$$amount$$", content);
                templateId = hfxSmsGeneralPurposeTemplateId1;
            }


        }

        // 组装要提交的参数
        JSONObject json = new JSONObject();
        JSONObject encryptJson = new JSONObject(); // 和飞信加密参数
        encryptJson.put("enterDeptId", hfxSmsEnterDeptId); // 企业ID  // 由我方写死
        encryptJson.put("contactIds", contactIds);	 // 联系人ID
        encryptJson.put("templateId", templateId); // 通用短信模板ID
        encryptJson.put("placeHolderContent",placeHolderContent); // 短信模板变量
        encryptJson.put("appKey",hfxSmsAppkey);

        json.put("nonce", UUID.randomUUID().toString().replaceAll("-", "")); // 随机串
        json.put("encrypt", AESEncryptUtil.aesEncrypt(encryptJson.toJSONString(), AESEncryptUtil.getAESKey(hfxSmsAeskey)));
        json.put("timeStamp", System.currentTimeMillis() + ""); // 时间戳
        json.put("secretId", hfxSmsSecretId); // 渠道ID
        json.put("signature", SignatureUtil.createSignature( json.getString("timeStamp") ,  json.getString("nonce"), json.getString("secretId"))); // 签名
        log.info(contactIds + " 联系人ID encrypt参数组装结果" + encryptJson.toJSONString());
        log.info(contactIds + " 联系人ID 最终提交参数组装结果" + json.toJSONString());

        return json.toJSONString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

}
